package 剑指;

import java.util.Arrays;

/**
 * 面试题60. n个骰子的点数
 * 把n个骰子扔在地上，所有骰子朝上一面的点数之和为s。输入n，打印出s的所有可能的值出现的概率。
 *
 *
 *
 * 你需要用一个浮点数数组返回答案，其中第 i 个元素代表这 n 个骰子所能掷出的点数集合中第 i 小的那个的概率。
 *
 *
 *
 * 示例 1:
 *
 * 输入: 1
 * 输出: [0.16667,0.16667,0.16667,0.16667,0.16667,0.16667]
 * 示例 2:
 *
 * 输入: 2
 * 输出: [0.02778,0.05556,0.08333,0.11111,0.13889,0.16667,0.13889,0.11111,0.08333,0.05556,0.02778]
 *
 *
 * 限制：
 *
 * 1 <= n <= 11
 */
public class medium_剑指_n个骰子的点数 {

    public static double[] dicesProbability(int n) {
        double[] dp = new double[6*n+1];
        double each = 1.0d/6.0d;
        for(int i = 1; i <= 6; i++){
           dp[i] = 1.0d/6.0d;
        }
        for(int i = 2; i <= n; i++){
            double[] tmp = new double[6*n+1];
            /**
             * 这里可以有两种解释，
             * 1 是 dp[z] 等于 dp[z-6]到dp[z-1] 之和 / 6
             * 2 是 新加入的骰子 从 1-6 更新上一次状态
             */
            for(int j = 1; j <= 6; j++){
                for(int z = 0; z < dp.length; z++){
                    if(dp[z] != 0){
                        tmp[z+j] += dp[z] * each;
                    }
                }
            }
            dp = tmp;
        }
        double[] result = new double[6*n+1-n];
        for(int i = 0; i < result.length; i++){
            result[i] = dp[n+i];
        }
        return result;
    }

    public static void main(String[] args){
        System.out.println(Arrays.toString(dicesProbability(1)));
    }
}
